/**
 * plugin.c - 钩子框架的示例插件
 *
 * 此文件演示如何创建一个向主框架注册
 * 额外钩子的插件。
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <unistd.h>
#include <time.h>

#include "../../include/hook_framework.h"

/* 声明原始函数指针 */
static char* (*original_getenv)(const char*) = NULL;
static pid_t (*original_getpid)(void) = NULL;

/* 自定义getenv()钩子，可以修改环境变量 */
char* getenv(const char *name) {
    /* 获取真实的getenv函数，如果尚未获取 */
    if (!original_getenv) {
        original_getenv = dlsym(RTLD_NEXT, "getenv");
        if (!original_getenv) {
            fprintf(stderr, "错误: 解析符号'getenv'失败: %s\n", dlerror());
            return NULL;
        }
    }
    
    /* 如果调试已启用，记录此调用 */
    log_message(LOG_DEBUG, "getenv(\"%s\")被插件拦截", name);
    
    /* 拦截特定环境变量 */
    if (strcmp(name, "HOME") == 0) {
        log_message(LOG_INFO, "插件拦截了HOME环境变量");
        return "/modified/home/path";
    }
    
    if (strcmp(name, "USER") == 0) {
        log_message(LOG_INFO, "插件拦截了USER环境变量");
        return "modified_user";
    }
    
    if (strcmp(name, "HOOK_TEST_VAR") == 0) {
        log_message(LOG_INFO, "插件拦截了HOOK_TEST_VAR环境变量");
        /* 返回一个动态值（插件正在工作！） */
        static char buffer[128];
        time_t now = time(NULL);
        struct tm* tm_now = localtime(&now);
        snprintf(buffer, sizeof(buffer), "插件已激活！[%02d:%02d:%02d]", 
                tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec);
        return buffer;
    }
    
    /* 对于其他变量，调用原始函数 */
    return original_getenv(name);
}

/* 自定义getpid()钩子 - 返回固定PID的愚蠢示例 */
pid_t getpid(void) {
    /* 获取真实的getpid函数，如果尚未获取 */
    if (!original_getpid) {
        original_getpid = dlsym(RTLD_NEXT, "getpid");
        if (!original_getpid) {
            fprintf(stderr, "错误: 解析符号'getpid'失败: %s\n", dlerror());
            return -1;
        }
    }
    
    /* 记录此调用 */
    pid_t real_pid = original_getpid();
    log_message(LOG_INFO, "插件拦截了getpid()，真实PID=%d，返回12345", real_pid);
    
    /* 返回一个假PID */
    return 12345;
}

/**
 * 初始化插件并注册钩子
 */
__attribute__((constructor))
static void init_plugin(void) {
    log_message(LOG_INFO, "示例插件正在初始化");
    
    /* 注意：我们不再需要显式注册钩子，因为我们直接替换了函数 */
    log_message(LOG_INFO, "示例插件已初始化 - 直接替换了getenv()和getpid()函数");
    
    /* 向stdout打印一条消息，让用户知道插件已加载 */
    printf("钩子框架示例插件已成功加载！\n");
}

/**
 * 插件卸载时清理
 */
__attribute__((destructor))
static void cleanup_plugin(void) {
    log_message(LOG_INFO, "示例插件正在关闭");
}
